package hos.http;

import org.json.JSONArray;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * <p>Title: HttpRequestBody </p>
 * <p>Description: 请求体 </p>
 * <p>Company: www.mapuni.com </p>
 *
 * @author : 蔡俊峰
 * @version : 1.0
 * @date : 2023-02-24 12:49
 */
public class HttpRequestBody extends HttpRequest<HttpRequestBody> implements HttpBaseRequestBody<HttpRequestBody> {

    private List<HttpFile> fileList = new ArrayList<>();

    private Object data;

    /**
     * 上传请求
     */
    private HttpTag.UploadListeners uploadProgressListeners = new HttpTag.UploadListeners();
    private boolean isFormEncoded = false;
    private boolean isMultipart = false;

    @Override
    public HttpRequestBody init() {
        method(HttpMethod.POST);
        if (fileList == null) {
            fileList = new ArrayList<>();
        }
        if (uploadProgressListeners == null) {
            uploadProgressListeners = new HttpTag.UploadListeners();
        }
        return super.init();
    }

    /**
     * @noinspection unchecked
     */
    @Override
    public HttpRequestBody data(Object data) {
        if (data != null) {
            if (data instanceof String) {
                if (((String) data).contains("{") || ((String) data).contains("[")) {
                    return json((String) data);
                }
                return txt((String) data);
            } else if (data instanceof byte[]) {
                return bytes((byte[]) data);
            } else if (data instanceof JSONObject) {
                return json((JSONObject) data);
            } else if (data instanceof JSONArray) {
                return json((JSONArray) data);
            } else if (data instanceof Map) {
                return json((Map<String, ?>) data);
            } else if (data instanceof List) {
                if (!((List<?>) data).isEmpty()) {
                    if (((List<?>) data).get(0) instanceof HttpFile) {
                        return file((List<HttpFile>) data);
                    } else if (((List<?>) data).get(0) instanceof Map) {
                        return json((List<Map<String, ?>>) data);
                    }
                }
            }
            this.data = data;
        }
        return this;
    }

    @Override
    public HttpRequestBody txt(String txt) {
        if (txt != null) {
            this.data = txt;
        }
        mediaType = HttpContentType.TXT;
        return this;
    }

    //<editor-fold desc="bytes">
    public HttpRequestBody bytes(byte[] bytes) {
        if (bytes != null) {
            this.data = bytes;
        }
        mediaType = HttpContentType.OCTET_STREAM;
        return this;
    }
    //</editor-fold>

    //<editor-fold desc="File">
    public HttpRequestBody file(String name, String file) {
        return file(name, null, file);
    }

    public HttpRequestBody file(String name, List<String> files) {
        if (files != null) {
            for (String file : files) {
                file(name, file);
            }
        }
        return this;
    }

    public HttpRequestBody file(String name, String fileName, String file) {
        if (file != null) {
            fileList.add(new HttpFile(name, fileName, file));
        }
        mediaType = HttpContentType.FORM;
        return this;
    }

    @Override
    public HttpRequestBody file(List<HttpFile> list) {
        if (list != null) {
            fileList.addAll(list);
        }
        mediaType = HttpContentType.FORM;
        return this;
    }

    public List<HttpFile> getFileList() {
        return fileList;
    }

    /**
     * 添加下载进度监听
     *
     * @param listener 监听事件
     */
    public HttpRequestBody addUploadListener(ProgressListener listener) {
        if (!uploadProgressListeners.contains(listener)) {
            uploadProgressListeners.add(listener);
        }
        return this;
    }

    public HttpTag.UploadListeners uploadProgressListeners() {
        return uploadProgressListeners;
    }

    //</editor-fold>

    //<editor-fold desc="JSON">

    /**
     * 添加Json为请求体
     */
    public HttpRequestBody json(JSONObject body) {
        if (body != null) {
            this.data = body.toString();
        }
        mediaType = HttpContentType.JSON;
        return this;
    }

    /**
     * 添加Json为请求体
     */
    public HttpRequestBody json(JSONArray body) {
        if (body != null) {
            this.data = body.toString();
        }
        mediaType = HttpContentType.JSON;
        return this;
    }

    /**
     * 添加Json为请求体
     */
    public HttpRequestBody json(String body) {
        if (body != null) {
            this.data = body;
        }
        mediaType = HttpContentType.JSON;
        return this;
    }

    /**
     * 添加Json为请求体
     */
    public HttpRequestBody json(Map<String, ?> body) {
        if (body != null) {
            this.data = JsonUtils.toJson(body);
        }
        mediaType = HttpContentType.JSON;
        return this;
    }

    @Override
    public HttpRequestBody json(List<Map<String, ?>> body) {
        if (body != null) {
            this.data = JsonUtils.toJson(body);
        }
        mediaType = HttpContentType.JSON;
        return this;
    }
    //</editor-fold>


    public Object getData() {
        return data;
    }

    @Override
    public HttpRequestBody isFormEncoded(boolean isFormEncoded) {
        this.isFormEncoded = isFormEncoded;
        return this;
    }

    @Override
    public HttpRequestBody isMultipart(boolean isMultipart) {
        this.isMultipart = isMultipart;
        return this;
    }

    @Override
    public boolean isFormEncoded() {
        return isFormEncoded;
    }

    @Override
    public boolean isMultipart() {
        return isMultipart;
    }

    @Override
    protected void check() {
        if (fileList == null) {
            fileList = new ArrayList<>();
        }
        if (uploadProgressListeners == null) {
            uploadProgressListeners = new HttpTag.UploadListeners();
        }
        super.check();
    }

    @Override
    public void clear() {
        fileList.clear();
        uploadProgressListeners.clear();
        data = null;
        super.clear();
    }
}
